package com.vaadin.thomas.contenttool;

import java.util.Locale;
import java.util.logging.Level;

import com.vaadin.thomas.contenttool.data.Model;
import com.vaadin.thomas.contenttool.data.ModelFactory;
import com.vaadin.thomas.contenttool.data.Version;
import com.vaadin.thomas.contenttool.exceptions.ValueNotFoundException;
import com.vaadin.thomas.contenttool.ui.Util;

/**
 * Main class for the Tool. Provides methods for fetching the translations of
 * given keys.
 * <p>
 * You can initialize as many instances of this class as you need; all instances
 * will connect to the same specified {@link Model} instance. This allows
 * multiple different tools in the same JVM.
 * 
 * @author Thomas Mattsson / Vaadin Ltd.
 */
public class ContentTool {

	public static final String PREVIEW_URIFRAGMENT = "preview";

	private final Config conf;
	private final Model model;

	private Locale currentLocale;

	private Version currentVersion;

	/**
	 * Creates a new ConfigTool instance with the specified configuration.
	 * 
	 * @param config
	 * @param initialLanguage
	 * @param bb
	 */
	public ContentTool(Config config, Locale initialLanguage) {

		conf = config;
		currentLocale = initialLanguage;

		Util.log(
				"Starting ContentTool instance for user id '"
						+ config.getUserIdToStore() + "' with model '"
						+ config.getModelId() + "'", Level.INFO, conf);

		model = ModelFactory.get(config.getModelId());

		currentVersion = model.getPreview();
	}

	/**
	 * @return the {@link Model} instance connected to this Tool.
	 */
	public Model getModel() {
		return model;
	}

	/**
	 * Gets a value for the given key in the language specified with
	 * {@link #setLang(Locale)}.
	 * <p>
	 * Checks for versioning and timed publishing.
	 * 
	 * @param key
	 * @return the localization if found; the identifier itself is returned
	 *         otherwise.
	 * @throws ValueNotFoundException
	 *             if a Value cannot be found and
	 *             {@link Config#throwWhenValueNotFound()} is set to
	 *             <code>true</code>.
	 */
	public String get(String key) throws ValueNotFoundException {
		return currentVersion.get(model, key, currentLocale);
	}

	/**
	 * @return The current language of returned values.
	 */
	public Locale getLang() {
		return currentLocale;
	}

	/**
	 * Use this method to change the language of the returned values.
	 * 
	 * @param newLang
	 */
	public void setLang(Locale newLang) {
		if (!currentLocale.equals(newLang)) {
			currentLocale = newLang;
		}
	}

	/**
	 * @return The currently used {@link Config}.
	 */
	public Config conf() {
		return conf;
	}

	public String getUserNameForUI() {
		return conf.getUserNameForAdminUI(conf.getUserIdToStore());
	}

	/**
	 * If set to <code>true</code>, key searches using {@link #get(String)} will
	 * return preview values instead of committed values. Often used in
	 * conjunction with URI mapping; when the user enters a specific URI, the
	 * application is initialized with the preview-mode enabled instead of the
	 * production mode.
	 * <p>
	 * Identical to calling {@link #setCurrentVersion(Version)} with the Preview
	 * or Production versions.
	 */
	public void setPreviewMode(boolean set) {
		currentVersion = set ? model.getPreview() : model.getProduction();
	}

	public boolean isPreviewMode() {
		return currentVersion.equals(model.getPreview());
	}

	/**
	 * Changes the version of return values for this instance of
	 * {@link ContentTool}
	 */
	public void setCurrentVersion(Version version) {
		currentVersion = version;
	}

	public Version getCurrentVersion() {
		return currentVersion;
	}
}
